package com.wsc.personalblog.service.impl;

import com.wsc.personalblog.DTO.LikeInfoDTO;
import com.wsc.personalblog.common.Constant;
import com.wsc.personalblog.exception.CLikeFailedException;
import com.wsc.personalblog.exception.UnlikeFailedException;
import com.wsc.personalblog.mapper.ArticleMapper;
import com.wsc.personalblog.mapper.CommentMapper;
import com.wsc.personalblog.mapper.LeaveAMessageMapper;
import com.wsc.personalblog.service.ArticleService;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class LikeServiceImpl {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private LeaveAMessageMapper leaveAMessageMapper;

    public void unlikeArticle(Integer articleId, Integer userId) {
        // 缓存我的所有文章id，便于判断传入文章id是否合法
        cacheArticleIdAll();
        //判断文章id合法性
        if(!isValExists(Constant.ARTICLE_ID_SET, articleId)){
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        String key = Constant.ARTICLE_PREFIX+articleId;
        if (!isKeyExists(key)) {
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 检查是否已点赞
        if(!isValExists(key,userId)){
            // 未点赞处理逻辑
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 已点赞处理逻辑
        redisTemplate.opsForSet().remove(key,userId);
    }

    public String likeArticle(Integer articleId, Integer userId) {
        // 缓存我的所有文章id，便于判断传入文章id是否合法
        cacheArticleIdAll();
        // 检查文章id是否合法
        if(!isValExists(Constant.ARTICLE_ID_SET, articleId)){
            throw new CLikeFailedException(Constant.C_LIKE_FAILED);
        }
        String key = Constant.ARTICLE_PREFIX + articleId;
        // 判断当前文章点赞信息对应的key是否存在，不存在就说明文章还没有被点赞过
        if (!isKeyExists(key)) {
            redisTemplate.opsForSet().add(key, userId);
            log.info(Constant.ARTICLE_PREFIX + articleId + "====" + Constant.C_LIKE_SUCCESSFUL);
            return Constant.C_LIKE_SUCCESSFUL;
        }
        // 检查该用户是否已经点赞该文章
        if(isValExists(key, userId)){
            //已点赞操作
            log.info(key + "====" + Constant.HAVE_LIKED);
            throw new CLikeFailedException(Constant.HAVE_LIKED);
        }
        // 未点赞操作
        // 将用户添加到点赞集合中
        redisTemplate.opsForSet().add(key, userId);
        log.info(key + "====" + Constant.C_LIKE_SUCCESSFUL);
        return Constant.C_LIKE_SUCCESSFUL;
    }
    private boolean isValExists(String key , Object val){
        if(key == null || val == null) return false;
        return redisTemplate.opsForSet().isMember(key, val);
    }
    private void cacheArticleIdAll(){
        boolean keyExists = isKeyExists(Constant.ARTICLE_ID_SET);
        if(keyExists) return;
        List<Integer> articleIdSet =  articleMapper.getArticleIdAll();
        Integer[] integers = articleIdSet.toArray(new Integer[0]);
        redisTemplate.opsForSet().add(Constant.ARTICLE_ID_SET,integers);
    }
    private boolean isKeyExists(String key) {
        if(key == null) return false;
        return redisTemplate.hasKey(key);
    }

    public LikeInfoDTO getLikeNumAndLikeStatus(Integer articleId,Integer userId) {
        String key = Constant.ARTICLE_PREFIX + articleId;
        LikeInfoDTO likeInfoDTO = new LikeInfoDTO();
        // 如果文章点赞数的key不存在，则表示该文章没人点赞
        if(!isKeyExists(key)) return likeInfoDTO;
        Long size = redisTemplate.opsForSet().size(key);
        likeInfoDTO.setLikeCount(size);
        if(isValExists(key, userId)) likeInfoDTO.setLikeStatus(1);
        return likeInfoDTO;
    }

    public void likeComment(Integer commentId, Integer userId) {
        // 缓存我的所有评论id，便于判断传入评论id是否合法
        cacheCommentIdAll();
        // 检查评论id是否合法
        if(!isValExists(Constant.COMMENT_ID_SET, commentId)){
            throw new CLikeFailedException(Constant.C_LIKE_FAILED);
        }
        String key = Constant.COMMENT_PREFIX + commentId;
        // 判断当前文章点赞信息对应的key是否存在，不存在就说明文章还没有被点赞过
        if (!isKeyExists(key)) {
            redisTemplate.opsForSet().add(key, userId);
            log.info(key + "====" + Constant.C_LIKE_SUCCESSFUL);
            return ;
        }
        // 检查该用户是否已经点赞该文章
        if(isValExists(key, userId)){
            //已点赞操作
            log.info(key + "====" + Constant.HAVE_LIKED);
            throw new CLikeFailedException(Constant.HAVE_LIKED);
        }
        // 未点赞操作
        // 将用户添加到点赞集合中
        redisTemplate.opsForSet().add(key, userId);
        log.info(key + "====" + Constant.C_LIKE_SUCCESSFUL);
    }

    private void cacheCommentIdAll(){
        boolean keyExists = isKeyExists(Constant.COMMENT_ID_SET);
        if(keyExists) return;
        List<Integer> commentIdSet =  commentMapper.getCommentIdAll();
        Integer[] integers = commentIdSet.toArray(new Integer[0]);
        redisTemplate.opsForSet().add(Constant.COMMENT_ID_SET,integers);
    }

    public void unlikeComment(Integer commentId, Integer userId) {
        // 缓存我的所有文章id，便于判断传入文章id是否合法
        cacheCommentIdAll();
        // 检查评论id是否合法
        if(!isValExists(Constant.COMMENT_ID_SET, commentId)){
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        String key = Constant.COMMENT_PREFIX + commentId;
        // 判断当前评论点赞信息对应的key是否存在，不存在就说明评论还没有被点赞过
        if (!isKeyExists(key)) {
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 检查是否已点赞
        if(!isValExists(key,userId)){
            // 未点赞处理逻辑
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 已点赞处理逻辑
        redisTemplate.opsForSet().remove(key,userId);
    }

    public LikeInfoDTO getCommentLikeNumAndLikeStatus(Integer commentId, Integer userId) {
        String key = Constant.COMMENT_PREFIX + commentId;
        LikeInfoDTO likeInfoDTO = new LikeInfoDTO();
        // 如果评论点赞数的key不存在，则表示该文章没人点赞
        if(!isKeyExists(key)) return likeInfoDTO;
        Long size = redisTemplate.opsForSet().size(key);
        likeInfoDTO.setLikeCount(size);
        if(isValExists(key, userId)) likeInfoDTO.setLikeStatus(1);
        return likeInfoDTO;
    }

    public LikeInfoDTO getLAMLikeNumAndLikeStatus(Integer lamId, Integer userId) {
        String key = Constant.LAM_PREFIX + lamId;
        LikeInfoDTO likeInfoDTO = new LikeInfoDTO();
        // 如果评论点赞数的key不存在，则表示该文章没人点赞
        if(!isKeyExists(key)) return likeInfoDTO;
        Long size = redisTemplate.opsForSet().size(key);
        likeInfoDTO.setLikeCount(size);
        if(isValExists(key, userId)) likeInfoDTO.setLikeStatus(1);
        return likeInfoDTO;
    }

    public void likeLAM(Integer lamId, Integer userId) {
        // 缓存我的所有留言id，便于判断传入留言id是否合法
        cacheLAMIdAll();
        // 检查留言id是否合法
        if(!isValExists(Constant.LAM_ID_SET, lamId)){
            throw new CLikeFailedException(Constant.C_LIKE_FAILED);
        }
        String key = Constant.LAM_PREFIX + lamId;
        // 判断当前留言点赞信息对应的key是否存在，不存在就说明留言还没有被点赞过
        if (!isKeyExists(key)) {
            redisTemplate.opsForSet().add(key, userId);
            log.info(key + "====" + Constant.C_LIKE_SUCCESSFUL);
            return ;
        }
        // 检查该用户是否已经点赞该文章
        if(isValExists(key, userId)){
            //已点赞操作
            log.info(key + "====" + Constant.HAVE_LIKED);
            throw new CLikeFailedException(Constant.HAVE_LIKED);
        }
        // 未点赞操作
        // 将用户添加到点赞集合中
        redisTemplate.opsForSet().add(key, userId);
        log.info(key + "====" + Constant.C_LIKE_SUCCESSFUL);
    }

    public void unlikeLAM(Integer lamId, Integer userId) {
        // 缓存我的所有文章id，便于判断传入文章id是否合法
        cacheLAMIdAll();
        // 检查评论id是否合法
        if(!isValExists(Constant.LAM_ID_SET, lamId)){
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        String key = Constant.LAM_PREFIX + lamId;
        // 判断当前评论点赞信息对应的key是否存在，不存在就说明评论还没有被点赞过
        if (!isKeyExists(key)) {
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 检查是否已点赞
        if(!isValExists(key,userId)){
            // 未点赞处理逻辑
            throw new UnlikeFailedException(Constant.UNLIKE_FAILED);
        }
        // 已点赞处理逻辑
        redisTemplate.opsForSet().remove(key,userId);
    }

    private void cacheLAMIdAll(){
        boolean keyExists = isKeyExists(Constant.LAM_ID_SET);
        if(keyExists) return;
        List<Integer> LAMIdSet =  leaveAMessageMapper.getLAMtIdAll();
        Integer[] integers = LAMIdSet.toArray(new Integer[0]);
        redisTemplate.opsForSet().add(Constant.LAM_ID_SET,integers);
    }
}
